package com.cloud.hotline.api.service.impl;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.cloud.hotline.api.bean.HotlineCalculateBean;
import com.cloud.hotline.api.bean.HotlineCalculateForm;
import com.cloud.hotline.api.bean.HotlineStreetCaculateBean;
import com.cloud.hotline.api.bean.HotlineUnitCaculateBean;
import com.cloud.hotline.api.consts.HotLineConsts;
import com.cloud.hotline.api.entity.ToHotlineRecord;
import com.cloud.hotline.api.mapper.ToHotlineRecordMapper;
import com.cloud.hotline.api.mapper.ToHotlineRevisitRecordMapper;
import com.cloud.hotline.api.mapper.ToHotlineStreetRecordMapper;
import com.cloud.hotline.api.mapper.ToHotlineUnitRecordMapper;
import com.cloud.hotline.api.service.HotlineStatService;
import com.cloud.hotline.common.utils.DateHelper;
import com.cloud.hotline.common.utils.RankStatHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class HotlineStatServiceImpl implements HotlineStatService {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private ToHotlineRevisitRecordMapper hotlineRevisitRecordMapper;

	@Autowired
	private ToHotlineStreetRecordMapper toHotlineStreetRecordMapper;

	@Autowired
	private ToHotlineUnitRecordMapper toHotlineUnitRecordMapper;

	@Autowired
	private ToHotlineRecordMapper toHotlineRecordMapper;

	@Override
	public List<?> calculate(HotlineCalculateForm form) {
		if (1 == form.getType()) {
			// 诉求三率
			List<HotlineCalculateBean> calcResults = null;
			List<HotlineCalculateBean> perDayCalcResults = null;
			// 市级回访
			if (1 == form.getResponseType()) {
				calcResults = hotlineRevisitRecordMapper.calculateCity(form);
				form.setEnd(DateHelper.getDateBeforeOrAfterDays(form.getEnd(), -1));
				perDayCalcResults = hotlineRevisitRecordMapper.calculateCity(form);
			} else if (2 == form.getResponseType()) {
				// 区级回访
				// 获取区域内的最大市级回访时间
				this.getMaxCityrevisit(form);
				calcResults = hotlineRevisitRecordMapper.calculateArea(form);
				form.setEnd(DateHelper.getDateBeforeOrAfterDays(form.getEnd(), -1));
				perDayCalcResults = hotlineRevisitRecordMapper.calculateArea(form);
			} else if (0 == form.getResponseType()) {
				// 全部
				// 获取区域内的最大市级回访时间
				List<java.util.Date> maxCityRevisitDate = jdbcTemplate.queryForList(
						"select max(dispatch_date) from to_hotline_record where "
								+ "data_type_id = 1 and delete_flag = 0 and city_revisit_date <= ?",
						java.util.Date.class, form.getEnd());
				if (null != maxCityRevisitDate && maxCityRevisitDate.size() == 1 && null != maxCityRevisitDate.get(0)) {
					// 最大市级回访时间
					form.setMaxCityRevisitDate(maxCityRevisitDate.get(0));
				} else {
					Calendar calendar = Calendar.getInstance();
					calendar.set(Calendar.YEAR, 2019);
					calendar.set(Calendar.MONTH, 1);
					calendar.set(Calendar.DATE, 1);
					form.setMaxCityRevisitDate(calendar.getTime());
				}
				calcResults = hotlineRevisitRecordMapper.calculateAll(form);
				form.setEnd(DateHelper.getDateBeforeOrAfterDays(form.getEnd(), -1));
				perDayCalcResults = hotlineRevisitRecordMapper.calculateAll(form);
			}

			// 计算趋势
			for (HotlineCalculateBean result : calcResults) {
				result.setQs("0.00");
				for (HotlineCalculateBean perDayResult : perDayCalcResults) {
					if (perDayResult.getDw().endsWith(result.getDw())) {
						DecimalFormat df = new DecimalFormat("0.00");
						String qs = df
								.format(Double.parseDouble(result.getSlhj()) - Double.parseDouble(result.getSlhj()));
						result.setQs(qs);
						continue;
					}
				}
			}
			form.setEnd(DateHelper.getDateBeforeOrAfterDays(form.getEnd(), 1));
			// 计算排名趋势
			if (null != calcResults && calcResults.size() > 0) {
				RankStatHelper.rankStatRevisit(calcResults);
			}
			return calcResults;
		} else if (2 == form.getType()) {
			// 街道承办
			List<HotlineStreetCaculateBean> strCaclResults = toHotlineStreetRecordMapper.caculate(form);
			List<Map<String, Object>> streetCount = jdbcTemplate.queryForList(
					"select unit_name, count(1) as c from to_hotline_record where delete_flag = 0"
							+ " and data_type_id = 3 and state_date >= ? and state_date <= ? group by unit_name",
					form.getStart(), form.getEnd());
			for (HotlineStreetCaculateBean strCaclResult : strCaclResults) {
				for (Map<String, Object> map : streetCount) {
					String uName = (String) map.get("unit_name");
					String count = map.get("c") + "";
					if (strCaclResult.getJdmc().endsWith(uName)) {
						if (!StringUtils.isEmpty(count)) {
							strCaclResult.setLjsl(Integer.valueOf(count));
						} else {
							strCaclResult.setLjsl(0);
						}
						continue;
					}
				}
			}
			if (null != strCaclResults && strCaclResults.size() > 0) {
				RankStatHelper.rankStatStreet(strCaclResults);
			}
			return strCaclResults;
		} else if (3 == form.getType()) {
			// 部门承办
			List<HotlineUnitCaculateBean> unitCaclResults = toHotlineUnitRecordMapper.caculate(form);
			List<Map<String, Object>> streetCount = jdbcTemplate.queryForList(
					"select unit_name, count(1) as c from to_hotline_record where delete_flag = 0"
							+ " and data_type_id = 4 and state_date >= ? and state_date <= ? group by unit_name",
					form.getStart(), form.getEnd());
			for (HotlineUnitCaculateBean strCaclResult : unitCaclResults) {
				for (Map<String, Object> map : streetCount) {
					String uName = (String) map.get("unit_name");
					String count = map.get("c") + "";
					if (strCaclResult.getMc().endsWith(uName)) {
						if (!StringUtils.isEmpty(count)) {
							strCaclResult.setLjsl(Integer.valueOf(count));
						} else {
							strCaclResult.setLjsl(0);
						}
						continue;
					}
				}
			}
			if (null != unitCaclResults && unitCaclResults.size() > 0) {
				RankStatHelper.rankStatUnit(unitCaclResults);
			}
			return unitCaclResults;
		}
		return null;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public PageInfo<?> detail(HotlineCalculateForm form, int pageNum, int pageSize) {
		if (form.getType() == 2 || form.getType() == 3) {
			return PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
				Example example = new Example(ToHotlineRecord.class);
				Example.Criteria criteria = example.createCriteria();
				if (!StringUtils.isEmpty(form.getName())) {
					criteria.andEqualTo("unitName", form.getName());
				}
				criteria.andEqualTo("dataTypeId", form.getType() + 1);
				criteria.andGreaterThanOrEqualTo("stateDate", form.getStart());
				criteria.andLessThanOrEqualTo("stateDate", form.getEnd());
				criteria.andEqualTo("deleteFlag", 0);
				toHotlineRecordMapper.selectByExample(example);
			});
		} else if (form.getType() == 1) {
			this.getMaxCityrevisit(form);
			// 诉求三率
			StringBuilder sqlBuilder = new StringBuilder("select * from to_hotline_record ");
			if (form.getResponseType() == 1) {
				// 市级回访
				sqlBuilder.append(" where unit_type = ").append(form.getKhType());
				sqlBuilder.append(" and dispatch_date >= str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getStart())).append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and dispatch_date <= str_to_date('").append(DateHelper.dateTimeToStr(form.getEnd()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and city_revisit_date < str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getEnd())).append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and data_type_id = " + HotLineConsts.DATA_TYPE_CITY_REVISIT);// 市级回访
				if (!StringUtils.isEmpty(form.getName()))
					sqlBuilder.append(" and unit_name = '").append(form.getName()).append("'");
			} else if (form.getResponseType() == 2) {
				// 区级回访
				sqlBuilder.append(" where unit_type = ").append(form.getKhType());
				sqlBuilder.append(" and dispatch_date > str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getMaxCityRevisitDate()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and dispatch_date > str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getMaxCityRevisitDate()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and revisit_date > str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getMaxCityRevisitDate()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and dispatch_date <= str_to_date('").append(DateHelper.dateTimeToStr(form.getEnd()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and revisit_date <= str_to_date('").append(DateHelper.dateTimeToStr(form.getEnd()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and data_type_id = " + HotLineConsts.DATA_TYPE_AREA_REVISIT);
				if (!StringUtils.isEmpty(form.getName()))
					sqlBuilder.append(" and unit_name = '").append(form.getName()).append("'");
			} else {
				// 考核类型：街道 / 部门
				sqlBuilder.append(" where unit_type = ").append(form.getKhType());
				// 考核时间
				sqlBuilder.append(" and dispatch_date >= str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getStart())).append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and dispatch_date <= str_to_date('").append(DateHelper.dateTimeToStr(form.getEnd()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and city_revisit_date < str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getEnd())).append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and data_type_id = " + HotLineConsts.DATA_TYPE_CITY_REVISIT);
				if (!StringUtils.isEmpty(form.getName()))
					sqlBuilder.append(" and unit_name = '").append(form.getName()).append("'");

				sqlBuilder.append(" union all ");

				// 考核类型：街道 / 部门
				sqlBuilder.append(" select * from to_hotline_record ");
				sqlBuilder.append(" where  unit_type = ").append(form.getKhType());
				// 考核时间
				sqlBuilder.append(" and dispatch_date > str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getStart())).append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and dispatch_date <= str_to_date('").append(DateHelper.dateTimeToStr(form.getEnd()))
						.append("','%Y-%m-%d %H:%i:%s')");

				sqlBuilder.append(" and revisit_date > str_to_date('").append(DateHelper.dateTimeToStr(form.getStart()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and revisit_date <= str_to_date('").append(DateHelper.dateTimeToStr(form.getEnd()))
						.append("','%Y-%m-%d %H:%i:%s')");

				sqlBuilder.append(" and dispatch_date > str_to_date('")
						.append(DateHelper.dateTimeToStr(form.getMaxCityRevisitDate()))
						.append("','%Y-%m-%d %H:%i:%s')");
				sqlBuilder.append(" and data_type_id = " + HotLineConsts.DATA_TYPE_AREA_REVISIT);
				if (!StringUtils.isEmpty(form.getName()))
					sqlBuilder.append(" and unit_name = '").append(form.getName()).append("'");
			}
			PageInfo records = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
				toHotlineRecordMapper.selectByDynamicSQL(sqlBuilder.toString());
			});
			List<Map<String, Object>> mapList = (List<Map<String, Object>>) records.getList();
			if (null != mapList && mapList.size() > 0) {
				List<ToHotlineRecord> list = JSON.parseArray(JSON.toJSONString(mapList), ToHotlineRecord.class);
				records.setList(list);
			}
			return records;
		}
		return null;
	}

	private void getMaxCityrevisit(HotlineCalculateForm form) {
		List<java.util.Date> maxCityRevisitDate = jdbcTemplate.queryForList(
				"select max(dispatch_date) from to_hotline_record where "
						+ "data_type_id = 1 and delete_flag = 0 and city_revisit_date <= ?",
				java.util.Date.class, form.getEnd());
		if (null != maxCityRevisitDate && maxCityRevisitDate.size() == 1 && null != maxCityRevisitDate.get(0)) {
			// 最大市级回访时间
			form.setMaxCityRevisitDate(maxCityRevisitDate.get(0));
		} else {
			Calendar calendar = Calendar.getInstance();
			calendar.set(Calendar.YEAR, 2019);
			calendar.set(Calendar.MONTH, 1);
			calendar.set(Calendar.DATE, 1);
			form.setMaxCityRevisitDate(calendar.getTime());
		}
	}

}
